//
// Created by Administrator on 2024/8/2.
//

#ifndef ROUTE_H
#define ROUTE_H
#include "inflection_point.h"
#include "../interfaces/base.h"
#include "../util/types.h"

namespace protocol {
    class Route final : public Sizeable, public Serializable {
        uint32_t routeId{};
        uint16_t routeProperty{};
        BcdTime startTime, endTime;
        uint16_t inflectionPointsCnt{};
        std::vector<InflectionPoint> inflectionPoints;
        uint16_t nameLength{};
        Container<char> name;

        IMPLEMENT_SIZEABLE(routeId, routeProperty, startTime, endTime, inflectionPointsCnt, inflectionPoints,
            nameLength, name)
    public:
        Route() = default;

        Route(const uint32_t route_id, const uint16_t route_property, const BcdTime &start_time,
            const BcdTime &end_time, const uint16_t inflection_points_cnt,
            const std::vector<InflectionPoint> &inflection_points, const uint16_t name_length,
            const Container<char> &name)
            : routeId(route_id),
              routeProperty(route_property),
              startTime(start_time),
              endTime(end_time),
              inflectionPointsCnt(inflection_points_cnt),
              inflectionPoints(inflection_points),
              nameLength(name_length),
              name(name) {
        }

        Route(const Route &other) = default;

        Route & operator=(const Route &other) = default;

        ~Route() override = default;

        void serialize(MessagePackWriter &writer) override {
            writer.writeUint(routeId);
            writer.writeUint(routeProperty);
            startTime.serialize(writer);
            endTime.serialize(writer);
            writer.writeUint(inflectionPointsCnt);
            for (auto point: inflectionPoints) {
                point.serialize(writer);
            }
            writer.writeUint(nameLength);
            name.serialize(writer);
        }

        void deserialize(MessagePackReader &reader) override {
            reader.readUint(routeId);
            reader.readUint(routeProperty);
            startTime.deserialize(reader);
            endTime.deserialize(reader);
            reader.readUint(inflectionPointsCnt);
            for (int i = 0; i < inflectionPointsCnt; ++i) {
                InflectionPoint p;
                p.deserialize(reader);
                inflectionPoints.push_back(p);
            }
            reader.readUint(nameLength);
            name = Container<char>(reader, nameLength);
        }
    };
}

#endif //ROUTE_H
